'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Imports Logger = Microsoft.Practices.EnterpriseLibrary.Logging.Logger

Public MustInherit Class Activty
    Implements Interfaces.IActivity
    Implements ComponentModel.INotifyPropertyChanged

    Private _Id As Integer
    Private _State As Interfaces.ActivityState
    Private _Logger As System.Text.StringBuilder

    Public Sub New(ByVal id As Integer)
        _Id = id
        _Logger = New System.Text.StringBuilder
    End Sub

    Public ReadOnly Property Id() As Integer Implements Interfaces.IActivity.Id
        Get
            Return _Id
        End Get
    End Property

    Public MustOverride ReadOnly Property Name() As String Implements Interfaces.IActivity.Name

    Public MustOverride ReadOnly Property Description() As String Implements Interfaces.IActivity.Description

    Public MustOverride ReadOnly Property AutoComplete() As Boolean Implements Interfaces.IActivity.AutoComplete

    Public ReadOnly Property Log() As String Implements Interfaces.IActivity.Log
        Get
            Return _Logger.ToString
        End Get
    End Property

    Public ReadOnly Property State() As Interfaces.ActivityState Implements Interfaces.IActivity.State
        Get
            Return _State
        End Get
    End Property

    Protected ReadOnly Property Logger() As System.Text.StringBuilder
        Get
            Return _Logger
        End Get
    End Property

    Public Sub Run() Implements Interfaces.IActivity.Run
        Verify()

        Try
            SetStarted()

            RunActivity()

            If AutoComplete Then SetCompleted()
        Catch ex As Exception
            SetFailed(ex.ToString)
           
            Core.Kernel.Exceptions.PublishException(ex)
        End Try
    End Sub

    Protected Overridable Sub Verify()
    End Sub

    Public Sub RunAsync() Implements Interfaces.IActivity.RunAsync
        Verify()

        Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf RunQueued))
    End Sub

    Private Sub RunQueued(ByVal state As Object)
        Run()
    End Sub

    Protected Sub SetStarted()
        SetState(Interfaces.ActivityState.Started)
        RaiseEvent ActivityStarted(Me, EventArgs.Empty)
        Kernel.Logger.Log("ActivityManager", TraceEventType.Information, "Activity [{0}] started.", Name)
    End Sub

    Protected Sub SetCompleted()
        SetState(Interfaces.ActivityState.Completed)
        RaiseEvent ActivityCompleted(Me, EventArgs.Empty)
        Kernel.Logger.Log("ActivityManager", TraceEventType.Information, "Activity [{0}] completed.", Name)
    End Sub

    Protected Sub SetFailed(ByVal message As String)
        SetState(Interfaces.ActivityState.Failed)
        RaiseEvent ActivityFailed(Me, EventArgs.Empty)
        Kernel.Logger.Log("ActivityManager", TraceEventType.Information, "Activity [{0}] failed. {1}", Name, message)
        Logger.AppendLine(message)
    End Sub

    Protected Sub SetState(ByVal newState As Interfaces.ActivityState)
        _State = newState
        OnPropertyChanged("State")
        OnPropertyChanged("Log")
    End Sub

    Protected MustOverride Sub RunActivity()

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    Protected Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs(propertyName))
    End Sub

    Public Event ActivityCompleted(ByVal sender As Object, ByVal e As System.EventArgs) Implements Interfaces.IActivity.ActivityCompleted

    Public Event ActivityFailed(ByVal sender As Object, ByVal e As System.EventArgs) Implements Interfaces.IActivity.ActivityFailed

    Public Event ActivityStarted(ByVal sender As Object, ByVal e As System.EventArgs) Implements Interfaces.IActivity.ActivityStarted

End Class
